package com.ruoyi.material.service.impl;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;

import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.constant.material.PurchaseConstants;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.material.domain.*;
import com.ruoyi.material.mapper.WarehouseOutMapper;
import com.ruoyi.material.mapper.WarehouseOutProductMapper;
import com.ruoyi.material.mapper.WarehouseStockMapper;
import com.ruoyi.material.mapper.WarehouseStockRecordMapper;
import com.ruoyi.material.service.IWarehouseOutService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * 出库单Service业务层处理
 *
 * @author wng
 * @date 2024-08-04
 */
@Service
public class WarehouseOutServiceImpl implements IWarehouseOutService {
    @Resource
    private WarehouseOutMapper warehouseOutMapper;
    @Resource
    private WarehouseOutProductMapper warehouseOutProductMapper;
    @Resource
    private WarehouseStockMapper warehouseStockMapper;
    @Resource
    private WarehouseStockRecordMapper warehouseStockRecordMapper;

    /**
     * 查询出库单
     *
     * @param id 出库单主键
     * @return 出库单
     */
    @Override
    public WarehouseOut selectWarehouseOutById(Long id) {
        WarehouseOut warehouseOut = warehouseOutMapper.selectWarehouseOutById(id);

        warehouseOut.getParams().put("products", warehouseOutProductMapper.selectWarehouseOutProductList(new WarehouseOutProduct() {{
            setOutId(id);
        }}));

        return warehouseOut;
    }

    /**
     * 查询出库单列表
     *
     * @param warehouseOut 出库单
     * @return 出库单
     */
    @Override
    public List<WarehouseOut> selectWarehouseOutList(WarehouseOut warehouseOut) {
        return warehouseOutMapper.selectWarehouseOutList(warehouseOut);
    }

    /**
     * 新增出库单
     *
     * @param warehouseOut 出库单
     * @return 结果
     */
    @Override
    @Transactional
    public int insertWarehouseOut(WarehouseOut warehouseOut) {
        warehouseOut.setCreateTime(DateUtils.getNowDate());
        warehouseOut.setId(Long.valueOf(DateUtils.parseDateToStr("yyyyMMddHHmmss", new Date()) + String.valueOf(ThreadLocalRandom.current().nextInt(1000, 9999))));
        int i = warehouseOutMapper.insertWarehouseOut(warehouseOut);
        if (i > 0) {
            Map<String, Object> params = new HashMap<String, Object>(1);
            //批量新增出库单物品关联
            List<WarehouseOutProduct> products = JSON.parseArray(JSON.toJSONString(warehouseOut.getParams().get("products")), WarehouseOutProduct.class);
            products.forEach(item -> {
                item.setOutId(warehouseOut.getId());
            });
            params.put("products", products);
            warehouseOutProductMapper.insertWarehouseOutProductBatch(params);

            //减去对应库存数量
            products.forEach(item -> {
                WarehouseStock warehouseStock = warehouseStockMapper.selectWarehouseStockById(item.getStockId());
                BigDecimal quantity_old = warehouseStock.getQuantity();

                warehouseStock.setQuantity(warehouseStock.getQuantity().subtract(item.getQuantity()));
                warehouseStockMapper.updateWarehouseStock(warehouseStock);

                //添加库存变动记录
                WarehouseStockRecord stockRecord = getStockRecord(item, quantity_old, warehouseStock, PurchaseConstants.StockTypeEnum.Out);
                warehouseStockRecordMapper.insertWarehouseStockRecord(stockRecord);
            });
        }
        return i;
    }

    private static WarehouseStockRecord getStockRecord(WarehouseOutProduct item, BigDecimal quantity_before, WarehouseStock stock, PurchaseConstants.StockTypeEnum stockTypeEnum) {
        WarehouseStockRecord stockRecord = new WarehouseStockRecord();
        stockRecord.setType(stockTypeEnum);
        stockRecord.setName(item.getName());

        stockRecord.setStockBefore(quantity_before);
        stockRecord.setStockAfter(stock.getQuantity());
        stockRecord.setUnit(item.getUnit());
        stockRecord.setfType(item.getfType());
        stockRecord.setfTypeSub(item.getfTypeSub());
        stockRecord.setWhetherImport(item.getWhetherImport());
        stockRecord.setCreateTime(new Date());

        stockRecord.setQuantity(stockRecord.getStockBefore().subtract(stockRecord.getStockAfter()).abs());
        return stockRecord;
    }

    /**
     * 修改出库单
     *
     * @param warehouseOut 出库单
     * @return 结果
     */
    @Override
    public int updateWarehouseOut(WarehouseOut warehouseOut) {
        warehouseOut.setUpdateTime(DateUtils.getNowDate());

        int i = warehouseOutMapper.updateWarehouseOut(warehouseOut);
        if (i > 0) {
            List<WarehouseOutProduct> products = JSON.parseArray(JSON.toJSONString(warehouseOut.getParams().get("products")), WarehouseOutProduct.class);

            List<WarehouseOutProduct> addList = new ArrayList<>(10);
            List<WarehouseOutProduct> updateList = new ArrayList<>(10);

            products.forEach(item -> {
                if (item.getId() != null) {
                    updateList.add(item);
                } else {
                    item.setOutId(warehouseOut.getId());
                    addList.add(item);
                }
            });
            products.clear();

            //新增出库物品关联
            if (!addList.isEmpty()) {
                warehouseOutProductMapper.insertWarehouseOutProductBatch(new HashMap<String, Object>(1) {{
                    put("products", addList);
                }});

                //变更库存
                for (WarehouseOutProduct item : addList) {
                    WarehouseStock warehouseStock = warehouseStockMapper.selectWarehouseStockById(item.getStockId());
                    BigDecimal quantity_old = warehouseStock.getQuantity();
                    warehouseStock.setQuantity(warehouseStock.getQuantity().subtract(item.getQuantity()));

                    warehouseStockMapper.updateWarehouseStock(warehouseStock);

                    //新增库存变动记录
                    WarehouseStockRecord stockRecord = getStockRecord(item, quantity_old, warehouseStock, PurchaseConstants.StockTypeEnum.Out);
                    warehouseStockRecordMapper.insertWarehouseStockRecord(stockRecord);
                }
            }

            //修改出库物品关联
            if (!updateList.isEmpty()) {
                for (WarehouseOutProduct item : updateList) {

                    WarehouseOutProduct warehouseOutProduct = warehouseOutProductMapper.selectWarehouseOutProductById(item.getId());

                    warehouseOutProductMapper.updateWarehouseOutProduct(item);

                    //变更库存
                    WarehouseStock warehouseStock = warehouseStockMapper.selectWarehouseStockById(item.getStockId());
                    BigDecimal quantity_old = warehouseStock.getQuantity();

                    BigDecimal subtract = item.getQuantity().subtract(warehouseOutProduct.getQuantity());

                    warehouseStock.setQuantity(warehouseStock.getQuantity().subtract(subtract));

                    warehouseStockMapper.updateWarehouseStock(warehouseStock);

                    //新增库存变动记录
                    WarehouseStockRecord stockRecord = getStockRecord(item, quantity_old, warehouseStock, PurchaseConstants.StockTypeEnum.Out);
                    warehouseStockRecordMapper.insertWarehouseStockRecord(stockRecord);

                }
            }

        }


        return i;
    }

    /**
     * 批量删除出库单
     *
     * @param ids 需要删除的出库单主键
     * @return 结果
     */
    @Override
    public int deleteWarehouseOutByIds(Long[] ids) {
        int i = warehouseOutMapper.deleteWarehouseOutByIds(ids);
        for (Long id : ids) {
            List<WarehouseOutProduct> warehouseOutProducts = warehouseOutProductMapper.selectWarehouseOutProductList(new WarehouseOutProduct() {{
                setOutId(id);
            }});

            for (WarehouseOutProduct item : warehouseOutProducts) {
                WarehouseStock warehouseStock = warehouseStockMapper.selectWarehouseStockById(item.getStockId());
                BigDecimal quantity_old = warehouseStock.getQuantity();
                //删除出库单，把库存重新加回去
                warehouseStock.setQuantity(warehouseStock.getQuantity().add(item.getQuantity()));
                warehouseStockMapper.updateWarehouseStock(warehouseStock);
                //新增库存变动记录
                WarehouseStockRecord stockRecord = getStockRecord(item, quantity_old, warehouseStock, PurchaseConstants.StockTypeEnum.Out_del);
                warehouseStockRecordMapper.insertWarehouseStockRecord(stockRecord);
            }
        }

        //批量删除出库单物品关联
        warehouseOutProductMapper.deleteWarehouseOutProductBatchByOutIds(ids);

        return i;
    }

    /**
     * 删除出库单信息
     *
     * @param id 出库单主键
     * @return 结果
     */
    @Override
    public int deleteWarehouseOutById(Long id) {
        return warehouseOutMapper.deleteWarehouseOutById(id);
    }
}
